package com.zb.controller;

import com.alibaba.druid.support.json.JSONUtils;
import com.zb.entity.UserOrder;
import com.zb.entity.vo.PurchaseHistoryVO;
import com.zb.enums.RoleEnum;
import com.zb.exception.MyException;
import com.zb.util.Base64Util;
import com.zb.util.BeanUtil;
import com.zb.util.SortUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import com.zb.entity.Address;
import com.zb.entity.User;
import com.zb.entity.vo.LoginUserVO;
import com.zb.enums.ResultEnum;
import com.zb.service.AddressService;
import com.zb.service.UserService;
import com.zb.util.Result;
import javax.annotation.Resource;
import java.util.*;

/**
 * 用户控制器
 * @author
 * @version 1.0
 **/
@Controller
@RequestMapping("/api/user")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private AddressService addressService;

    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @GetMapping("/info")
    public ModelAndView getUserInfo(@RequestParam("userId") String userId) {
        ModelAndView modelAndView = new ModelAndView("info");
        User user = userService.findById(Base64Util.decode(userId));
        modelAndView.addObject("user", user);
        modelAndView.addObject("address", user.getAddresses());
        modelAndView.addObject("wants", user.getWants());
        modelAndView.addObject("orders", user.getUserOrders());

        return modelAndView;
    }

    /**
     * 修改用户信息
     *
     * @param userId 用户id
     * @return Result
     */
    @PostMapping("/info")
    @ResponseBody
    public Result modifyUserInfo(@RequestBody String jsonUser, @RequestParam("userId") String userId) {
        userService.updateUserInfo(jsonUser, Base64Util.decode(userId));
        return Result.ok("修改用户信息成功", null);
    }

    /**
     * 处理用户登录
     *
     * @return Result
     */
    @PostMapping("/login")
    @ResponseBody
    public Result login(@RequestBody Map<String, Object> map) {
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        LoginUserVO loginUser = userService.login(username, password);
        if(Objects.isNull(loginUser)){
            throw new MyException("用户登录失败！");
        }
        Map<String, Object> data = new HashMap<>(16);
        data.put("userId", loginUser.getId());
        Result result = Result.ok(data);
        RoleEnum roleEnum = RoleEnum.getByName(loginUser.getRole());
        if(Objects.isNull(roleEnum)){
            throw new MyException("非法的用户权限！");
        }
        switch(roleEnum){
            case USER:
                result.injectEnum(ResultEnum.USER_LOGIN);
                break;
            case ADMIN:
                result.injectEnum(ResultEnum.ADMIN_LOGIN);
                break;
            case ROOT:
                result.injectEnum(ResultEnum.ROOT_LOGIN);
                break;
            default:
                throw new MyException("非法的用户权限！");
        }

        return result;
    }

    /**
     * 用户注册
     *
     * @param user 用户
     * @return 返回消息
     */
    @PostMapping("/register")
    @ResponseBody
    public Result register(@RequestBody User user) {
        userService.insertSelective(user);
        return Result.ok("注册成功", null);
    }

    /**
     * 用户未登录处理
     *
     * @return Result
     */
    @RequestMapping("/un_auth")
    public String unAuth() {
        return "login";
    }

    /**
     * 用户未授权处理
     *
     * @return Result
     */
    @RequestMapping("/unauthorized")
    public String unauthorized() {
        return "accessDenied";
    }

    /**
     * 新增用户地址
     *
     * @param userId 用户id
     * @param map    地址详情
     * @return 个人主页
     */
    @PostMapping("/addAddress")
    @ResponseBody
    public Result addAddress(@RequestParam("userId") String userId, @RequestBody Map<String, String> map) {
        Address newAddress = new Address();
        newAddress.setDetail(map.get("address"));
        newAddress.setUser(userService.findById(Base64Util.decode(userId)));
        addressService.insertSelective(newAddress);
        return Result.ok("添加成功", null);
    }

    /**
     * 删除用户地址
     *
     * @param addressId 地址id
     * @return 用户主页
     */
    @GetMapping("/delAddress")
    public String deleteAddress(@RequestParam("addressId") long addressId) {
        long userId = addressService.findById(addressId).getUser().getId();
        addressService.deleteById(addressId);
        return "redirect:/api/user/info?userId=" + Base64Util.encode(userId);
    }


    /**
     * 用户关注某用户
     *
     * @param followeeId 用户id
     * @param followerId 要关注的用户id
     * @return <关注者，被关注者>
     */
    @RequestMapping("/follow")
    @ResponseBody
    public Result followUser(@RequestParam("followerId") String followerId,@RequestParam("followeeId") String followeeId) {
        User user = userService.findById(Base64Util.decode(followerId));
        System.out.println("following user:");
        System.out.println("followerId:" + followerId + " followeeId:" + followeeId);
        System.out.println("after decode:" + " followerId:" + Base64Util.decode(followerId));
        if (StringUtils.isBlank(user.getFollowedUsers())) {
            user.setFollowedUsers(followeeId);
        } else {
            user.setFollowedUsers(user.getFollowedUsers() + "," + followeeId);
        }

        userService.updateUser(user);
        return Result.ok("关注成功", null);

    }

    /**
     * 用户取关某用户
     *
     * @param followeeId 用户id
     * @param followerId 要取关的用户id
     *
     * @return <关注者，被关注者>
     */
    @RequestMapping("/unfollow")
    @ResponseBody
    public Result unfollowUser(@RequestParam("followerId") String followerId,@RequestParam("followeeId") String followeeId) {
        User user = userService.findById(Base64Util.decode(followerId));
        System.out.println("unfollowing user:");
        System.out.println("followerId:"+followerId+" followeeId:"+followeeId);
        System.out.println("after decode:"+" followerId:"+Base64Util.decode(followerId));
        if(StringUtils.isBlank(user.getFollowedUsers())){
            return Result.error("未关注该用户！" , null);
        }

        String[] followedUsers = user.getFollowedUsers().split(",");
        String newFollowedUsers = "";

        for(String followedUser:followedUsers){
            if(!followeeId.equals(followeeId)){
                newFollowedUsers+=followedUser;
                newFollowedUsers+=",";
            }
        }
        if(newFollowedUsers.isEmpty()){
            user.setFollowedUsers("");
        }else{
            newFollowedUsers=newFollowedUsers.substring(0,newFollowedUsers.length()-1);
            user.setFollowedUsers(newFollowedUsers);
        }

        userService.updateUser(user);
        return Result.ok("关注成功" , null);
    }


    /**
     * 判断用户是否已关注某用户
     *
     * @param followeeId 用户id
     * @param followerId 要关注的用户id
     *
     * @return <关注者，被关注者>
     */
    @GetMapping("/ifFollowed")
    @ResponseBody
    public Result ifAlreadyFollowed(@RequestParam("followerId") String followerId,@RequestParam("followeeId") String followeeId) {
        User user = userService.findById(Base64Util.decode(followerId));
        System.out.println("followerId:"+followerId+" followeeId:"+followeeId);
        System.out.println("after decode:"+" followerId:"+Base64Util.decode(followerId));
        if(StringUtils.isBlank(user.getFollowedUsers())){
            System.out.println("未关注");
            return Result.ok("false",null);
        }else{
            if(user.getFollowedUsers().contains(followeeId)){
                System.out.println("已关注");
                return Result.ok("true",null);
            }else{
                System.out.println("未关注");
                return Result.ok("false",null);
            }
        }
    }


    /**
     * 获取用户关注的所有其它用户
     *
     * @param userId 用户id
     * @return 用户关注者列表
     */
    @GetMapping("/getFollowedUsers")
    @ResponseBody
    public String getFollowedUsers(@RequestParam("userId") long userId) {
        User user = userService.findById(userId);
        // 如要返回字符串列表形式，可通过split(",");
        String followedUsers = user.getFollowedUsers();
        return JSONUtils.toJSONString(followedUsers);
    }

    /**
     * 获取用户的粉丝
     *
     * @param userId 用户id
     * @return 用户关注者列表
     */
    @GetMapping("/getFollowers")
    @ResponseBody
    public String getFollowers(@RequestParam("userId") long userId) {
        List<User> followedUsers = userService.findFollowersById(userId);
        String followedIds = "";
        for (User user : followedUsers) {
            followedIds += user.getId();
            followedIds += ",";
        }
        return JSONUtils.toJSONString(followedIds);
    }

    /**
     * 获取用户的粉丝数排行
     *
     * @return 用户按粉丝数排行列表
     */
    @GetMapping("/followerCountRanking")
    @ResponseBody
    public List<Map.Entry<String, Long>> getFollowerCountRanking() {
        List<User> users = userService.getAllUsers();
        // map 存储<id,粉丝数>
        Map<String, Long> followerCountMap = new HashMap<>(16);
        for (User user : users) {
            String name = user.getUsername();
            long followerCnt = userService.getFollowerCountById(user.getId());
            if (name == null) {
                name = user.getRealName();
            }
            followerCountMap.put(name, followerCnt);
        }
        List<Map.Entry<String, Long>> ranking = SortUtil.mapSort(followerCountMap);

        return ranking;
    }


    /**
     * 获取用户的已购商品记录统计
     *
     * @param userId
     *            用户id
     * @return 用户关注者列表
     */
    @GetMapping("/purchaseRecord")
    @ResponseBody
    @Sql
    public List<PurchaseHistoryVO> getPurchaseRecord(@RequestParam("userId") long userId) {
        User user = userService.findById(userId);
        if(Objects.isNull(user)){
            return new ArrayList();
        }
        List<UserOrder> userOrders = user.getUserOrders();
        if(Objects.isNull(userOrders)){
            return new ArrayList();
        }
        List<PurchaseHistoryVO> purchaseHistories = new ArrayList();
        for(UserOrder userOrder:userOrders){
            purchaseHistories.add(BeanUtil.copyPropertiesToVO(userOrder));
        }

        return purchaseHistories;
    }
}
